package com.proximity.json;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URLConnection;

import com.google.gson.Gson;

public class JsonHelper {
	
	private static Gson gson = new Gson();
	
//	public static void callMethodJson(String urlJson) {
//		
//	}
//	
//	public static void callMethodJson(String urlJson, Object inputObject) {
//		
//	}
	
	public static <T> T callMethodJson(String urlJson, Class<T> outputClass) {
		T out = null;
		try {
			URL url = new URL(urlJson);
			URLConnection conn = url.openConnection();
			out = readerObject(conn, outputClass);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return out;
	}
	
	public static <T> T callMethodJson(String urlJson, Object inputObject, Type outputType) {
		T out = null;
		try {
			URL url = new URL(urlJson);
			URLConnection conn = url.openConnection();
			writeObject(conn, inputObject);
			out = readerObject(conn, outputType);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return out;
	}
	
	private static void writeObject(URLConnection conn, Object inputObject) {
		conn.setDoOutput(true);
		String serializedObject = null;
		OutputStreamWriter writer = null;
		try {
			serializedObject = serializeObject(inputObject);
			writer = new OutputStreamWriter(conn.getOutputStream());
	        writer.write(serializedObject);
	        writer.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				writer.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}
	
	private static <T> T readerObject(URLConnection conn, Type outType) {
		
		T out = null;
		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			StringBuffer sb = new StringBuffer();
			String line;
            while ((line = reader.readLine()) != null) {
            	sb.append(line);
            }
			out = gson.fromJson(sb.toString(), outType);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try { 
				reader.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return out;
		
	}
	
//	private static <T> T writeReader(String strUrl, Object parameter, Class<T> response) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
//		//Build parameter string
//		String data = serializeObject(parameter);
//        T out = null;
//        try {
//            
//            // Send the request
//            URL url = new URL(strUrl);
//            URLConnection conn = url.openConnection();
//            conn.setDoOutput(true);
//            OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
//            
//            //write parameters
//            writer.write(data);
//            writer.flush();
//            
//            // Get the response
//            StringBuffer answer = new StringBuffer();
//            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//            String line;
//            while ((line = reader.readLine()) != null) {
//                answer.append(line);
//            }
//            writer.close();
//            reader.close();
//            
//            //Output the response
//            out = gson.fromJson(answer.toString(), response);
//            
//        } catch (MalformedURLException ex) {
//            ex.printStackTrace();
//        } catch (IOException ex) {
//            ex.printStackTrace();
//        }
//		
//		return out;
//		
//	}
	
	private static String serializeObject(Object obj) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		
		Method[] methods = obj.getClass().getMethods();
		StringBuffer out = new StringBuffer();
		for (Method method : methods) {
			String name = null;
			if (method.getName().startsWith("get")) {
				name = method.getName().replaceFirst("get", ""); 
			} else if (method.getName().startsWith("is")) {
				name = method.getName().replaceFirst("is", ""); 
			}
			
			if (name!=null && !name.equals("Class")) {
				name = name.substring(0, 1).toLowerCase() + name.substring(1, name.length());
				out.append(name+"="+method.invoke(obj)+"&");
			}
			
		}
		
		return out.substring(0, out.length()-1);
		
	}

	
}
